package com.gitee.deament.server.core.cli.db.set;

import com.gitee.deament.server.config.SystemConfig;
import com.gitee.deament.server.core.annotation.CliHander;
import com.gitee.deament.server.core.cli.AbstractCli;
import com.gitee.deament.server.core.data.ConnectData;
import com.gitee.deament.server.core.data.DBData;
import com.gitee.deament.server.core.data.datatype.Value;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * SDIFF key [key …]
 * 可用版本： >= 1.0.0
 * 时间复杂度: O(N)， N 是所有给定集合的成员数量之和。
 * 返回一个集合的全部成员，该集合是所有给定集合之间的差集。
 *
 * 不存在的 key 被视为空集。
 *
 * 返回值
 * 一个包含差集成员的列表。
 * @author deamemnt
 */
@CliHander(command = "SDIFF")
public class SDIFFcli extends AbstractCli {
    @Override
    public void executeCli(ChannelHandlerContext channelHandlerContext, String command) {
        List<String> cliValues = getValues(command);
        if (cliValues.size() < 2) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ERR wrong number of arguments for 'SDIFF' command"));
            return;
        }
        int db = ConnectData.SELECT_DB_STORAGE.getUseDB(channelHandlerContext.channel().id().asLongText());
        DBData dbData = SystemConfig.dbData;
        String key = cliValues.get(1);
        try {
            Value<Set<String>> set = dbData.getSet(db, key);
            if(set ==null && set.getValue()==null || set.getValue().size()==0){
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(""));
                return;
            }
            HashSet<String> result =(HashSet<String>) ((HashSet<String>) set.getValue()).clone();
            for(int i=1;i<cliValues.size();i++){
                Value<Set<String>> other = dbData.getSet(db, cliValues.get(i));
                if(other ==null && other.getValue()==null || other.getValue().size()==0){
                    continue;
                }
                result.removeAll(other.getValue());
            }
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(result.toString()));
        }catch (Exception e){
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(e.getMessage()));
            return;
        }
    }
}
